#include "Stdafx.h"
#include "Decoder.h"
#include <windows.h>

namespace FFMpegDecoder 
{
	/*****************************************************************************/
	Decoder::Decoder() : 
		m_pVideoDecoder(nullptr)
	{
	}
	/*****************************************************************************/
	bool Decoder::Initialize(int iWidth, int iHeight)
	{
		m_pVideoDecoder = new CVideoDecoder();
		if (!m_pVideoDecoder->Initialize("h264", iWidth, iHeight, 0, 1))
		{
			delete(m_pVideoDecoder);
			m_pVideoDecoder = nullptr;
			return false;
		}

		return true;
	}
	/*****************************************************************************/
	bool Decoder::Decode(array<System::Byte> ^inBuffer, array<System::Byte> ^outBitmapBuffer,
								unsigned long nDestWidth, unsigned long nDestHeight, int stride, bool bDecodeToRGB)
	{
		bool bResult;
		int bIsFrameFinished = 0;
		unsigned char* pInputBuffer;
		unsigned char* pOutputBuffer;

		if (m_pVideoDecoder == nullptr)
			return false;

		/* Allocate the input buffer */
		pInputBuffer = (unsigned char*)malloc(inBuffer->Length * sizeof(unsigned char));
		/* And fill it */
		System::Runtime::InteropServices::Marshal::Copy(inBuffer, 0, (System::IntPtr)pInputBuffer, inBuffer->Length);
		/* Allocate the output buffer */
		pOutputBuffer = (unsigned char*)malloc(outBitmapBuffer->Length * sizeof(unsigned char));
		
		/* Call thg handler */
		bResult = m_pVideoDecoder->Decode(pInputBuffer, inBuffer->Length, pOutputBuffer, outBitmapBuffer->Length, nDestWidth, nDestHeight, stride, bDecodeToRGB, &bIsFrameFinished);

		/* Copy the output to the bitmap array */
		System::Runtime::InteropServices::Marshal::Copy((System::IntPtr)pOutputBuffer, outBitmapBuffer, 0, outBitmapBuffer->Length);

		/* And free the allocations */
		free(pInputBuffer);
		free(pOutputBuffer);

		return bResult;
	}
	/*****************************************************************************/
	bool Decoder::Terminate()
	{
		bool bResult;

		if (m_pVideoDecoder == nullptr)
			return false;

		bResult = m_pVideoDecoder->Terminate(true);
		delete(m_pVideoDecoder);
		m_pVideoDecoder = nullptr;

		return bResult;
	}
	/*****************************************************************************/
}